import socket
import selectors
import struct

sel = selectors.DefaultSelector()


def accept(sock, mask):
    conn, addr = sock.accept()
    print("accepted", conn, ", from", addr)
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)


def read(conn, mask):
    data = conn.recv(1000)
    if data:
        print("echoing", repr(data), "to", conn)
        conn.send(data)
    else:
        print("closing", conn)
        sel.unregister(conn)
        conn.close()


sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# fix: address already in use
# 设置SO_REUSEADDR选项
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 设置SO_LINGER选项
linger_option = struct.pack('ii', 1, 0)  # l_onoff=1, l_linger=0
sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, linger_option)

sock.bind(("localhost", 6677))
sock.listen(10)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)

while True:
    events = sel.select()
    for key, mask in events:
        callback = key.data
        callback(key.fileobj, mask)
